package main

import (
	"encoding/json"
	"fmt"
	"github.com/dlclark/regexp2"
	"github.com/shopspring/decimal"
	"math"
	"math/big"
	"reflect"
	"sort"
	"strconv"
	"strings"
	"time"
	"unicode/utf8"
)

// string转换类型uint
func StringToUInt(str string) (uint, error) {
	result, err := strconv.Atoi(str)
	return uint(result), err
}

// string转换类型int
func StringToInt(str string) (int, error) {
	result, err := strconv.Atoi(str)
	return result, err
}

// string转float64
func StringToFloat64(str string) (float64, error) {
	result, err := strconv.ParseFloat(str, 64)
	return result, err
}

// 获取指定字符串前缀内容(包括该字符串)
func StringCutPrefix(str string, rawStr string) string {
	index := strings.Index(str, rawStr)
	if index > 0 {
		return str[0 : index+len(rawStr)]
	}
	return str
}

// 格式化字符串
func StringFormat(str string, attr interface{}) string {
	return fmt.Sprintf(str, attr)
}

// 通过数组参数格式化字符串
func StringFormatByArray(str string, arr []string) string {
	var temp []interface{}
	for _, v := range arr {
		temp = append(temp, v)
	}
	str = fmt.Sprintf(str, temp...)
	return str
}

// 将数据类型统一转为string
func VariableToString(data interface{}) string {
	switch t := data.(type) {
	case int:
		return IntToString(data.(int))
	case int64:
		return Int64ToString(data.(int64))
	case float64:
		return Float64ToString(data.(float64))
	case float32:
		return FloatToString(data.(float32))
	case string:
		return data.(string)
	default:
		_ = t
		return data.(string)
	}
}

func HaveEmojiChar(str string) bool {
	runeCount := utf8.RuneCountInString(str)
	for _, char := range str {
		if utf8.RuneLen(char) >= 4 {
			return true
		}
		runeCount--
		if runeCount == 0 {
			break
		}
	}
	return false
}

// float64转string
func Float64ToString(value float64) string {
	n := decimal.NewFromFloat(value)
	return n.String()
}

// float32转string
func FloatToString(input_num float32) string {
	// to convert a float number to a string
	return strconv.FormatFloat(float64(input_num), 'f', 6, 64)
}

// 四舍五入保留指定位数的小数
func RoundHalfUp(x string, num float64) float64 {
	// math.Round(x*100) / 100
	decimalDigits := math.Pow(10, num) //保留的位数计算
	xf, _, err := big.ParseFloat(x, 10, 256, big.ToNearestEven)
	if err != nil {
		panic(err)
	}
	xf100, _ := new(big.Float).Mul(xf, big.NewFloat(decimalDigits)).Float64()
	return math.Round(xf100) / float64(decimalDigits)
}

// int转换类型string
func IntToString(value int) string {
	return strconv.Itoa(value)
}

// int64转换类型string
func Int64ToString(value int64) string {
	return strconv.FormatInt(value, 10)
}

// float64转int
func Float64ToInt(f float64) int {
	i, _ := strconv.Atoi(fmt.Sprintf("%1.0f", f))
	return i
}

// 将数据类型统一转为int
func VariableToInt(data interface{}) int {
	switch t := data.(type) {
	case int:
		return data.(int)
	case int64:
		tmp, _ := StringToInt(Int64ToString(data.(int64)))
		return tmp
	case float64:
		return Float64ToInt(data.(float64))
	case float32:
		return int(data.(float32))
	case string:
		if data.(string) == "" {
			return 0
		}
		var tmp float64
		_, err := fmt.Sscanf(data.(string), "%f", &tmp)
		if err != nil {
			panic(err)
		}
		return Float64ToInt(tmp)
	default:
		_ = t
		return data.(int)
	}
}

func ToJson(data interface{}) (string, error) {
	newJson, err := json.Marshal(data)
	if err != nil {
		return "", err
	}
	return string(newJson), nil
}

type Test struct {
	TestData string `json:"test_data"`
}

type ShowPlayerData struct {
	PlayerData       ShowPlayerDataPlayerData       `json:"player_data"`
	PlayerHonor      []ShowPlayerDataPlayerHonor    `json:"player_honor"`
	PlayerHonorCount ShowPlayerDataPlayerHonorCount `json:"player_honor_count"`
}

// 战队选手库-选手详情-选手基础信息-选手信息
type ShowPlayerDataPlayerData struct {
	PlayerId   int    `json:"player_id"`
	PlayerName string `json:"player_name"`
	AvatarURL  string `json:"avatar_url"`
	PhotoURL   string `json:"photo_url"`
	CountryId  string `json:"country_id"`
}

// 战队选手库-选手详情-选手基础信息-选手荣誉
type ShowPlayerDataPlayerHonor struct {
	TournamentId        int                               `json:"tournament_id"`
	TournamentName      string                            `json:"tournament_name"`
	TournamentAlias     string                            `json:"tournament_alias"`
	TournamentStartTime int                               `json:"tournament_start_time"`
	TournamentEndTime   int                               `json:"tournament_end_time"`
	FistCup             int                               `json:"fist_cup"`
	SecondCup           int                               `json:"second_cup"`
	ThirdCup            int                               `json:"third_cup"`
	TeamData            ShowPlayerDataPlayerHonorTeamData `json:"team_data"`
}

// 战队选手库-选手详情-选手基础信息-选手荣誉-队伍信息
type ShowPlayerDataPlayerHonorTeamData struct {
	TeamId     int    `json:"team_id"`
	TeamName   string `json:"team_name"`
	TeamTag    string `json:"team_tag"`
	TeamDomain string `json:"team_domain"`
	CountryID  string `json:"country_id"`
	Bgcolor    string `json:"bgcolor"`
	LogoURL    string `json:"logo_url"`
	H5LogoURL  string `json:"h5_logo_url"`
	Pattern    int    `json:"pattern"`
}

// 战队选手库-选手详情-选手基础信息-选手荣誉统计
type ShowPlayerDataPlayerHonorCount struct {
	FistCup   int `json:"fist_cup"`
	SecondCup int `json:"second_cup"`
	ThirdCup  int `json:"third_cup"`
}

func MouldId(id int) string {
	pre := strconv.Itoa((id + 3) * id)
	if len(pre) < 4 {
		pre = pre + "1586"
	}
	return pre[:4] + strconv.Itoa(id)
}

func UnMouldId(id string) int {
	vId := id[4:]
	vIdInt, _ := strconv.Atoi(vId)
	pre := strconv.Itoa((vIdInt + 3) * vIdInt)
	if len(pre) > 4 {
		pre = pre[:4]
	} else if len(pre) < 4 {
		pre = pre + "1586"
		pre = pre[:4]
	}

	if !strings.Contains(id, pre) {
		return -1
	}

	fId := strings.Replace(id, pre, "", 1)
	fIdInt, _ := strconv.Atoi(fId)
	return fIdInt
}

func RegexValidate(value string, rule string) bool {
	validate := map[string]string{
		"require":  ".+",
		"email":    "^\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$",
		"username": "^[^\\\\%\"'@#*<>()~]+$", // 排除的字符 === true
		"teamtag":  "^[a-zA-Z0-9_ .-]+$",
		"domain":   "^[a-zA-Z0-9_]+$",
		"url":      "^http(s?)://(?:[A-za-z0-9-]+\\.)+[A-za-z]{2,4}(?:[/\\?#][/=\\?%\\-&~`@[\\]':+!.#\\w]*)?$",
		"currency": "^\\d+(\\.\\d+)?$",
		"number":   "^\\d+$",
		"zip":      "^\\d{6}$",
		"mobile":   "^1[3456789]\\d{9}$",
		"integer":  "^[-+]?\\d+$",
		"double":   "^[-+]?\\d+(\\.\\d+)?$",
		"english":  "^[A-Za-z]+$",
		"field":    "^[a-zA-Z]+[a-zA-Z0-9_]{0,32}+$",
		"password": "^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\\W_]+$)(?![a-z0-9]+$)(?![a-z\\W_]+$)(?![0-9\\W_]+$)[a-zA-Z0-9\\W_]{8,16}$",
	}

	if r, ok := validate[strings.ToLower(rule)]; ok {
		rule = r
	}
	reg, _ := regexp2.Compile(rule, 0)
	matched, _ := reg.FindStringMatch(value)
	var res string
	if matched != nil {
		res = matched.String()
	}
	if res == "" {
		return false
	}
	return true
}

// 获取指定时区的Location，如果出错则返回nil
func getTimeLocation() *time.Location {
	location, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		// 可以记录日志或其他适当的错误处理
		return nil
	}
	return location
}

// 获取当前时间戳，如果无法获取指定时区，则返回服务器当前时间戳
func Now() int64 {
	location := getTimeLocation()
	if location != nil {
		return time.Now().In(location).Unix()
	}
	return time.Now().Unix()
}

// 获取当前格式化时间
func NowTimeFormat(str string) string {
	location := getTimeLocation()
	str = strings.Replace(str, "Y", "2006", -1)
	str = strings.Replace(str, "y", "06", -1)
	str = strings.Replace(str, "m", "01", -1)
	str = strings.Replace(str, "d", "02", -1)
	str = strings.Replace(str, "h", "15", -1)
	str = strings.Replace(str, "i", "04", -1)
	str = strings.Replace(str, "s", "05", -1)
	if location != nil {
		time.Now().In(getTimeLocation()).Format(str)
	}
	return time.Now().Format(str)
}

type SearchGpTeam struct {
	Id             int    `gorm:"column:team_id;primary_key;AUTO_INCREMENT" json:"team_id"`
	TeamName       string `json:"team_name"`
	TeamTag        string `json:"team_tag"`
	LogoUrl        string `json:"logo_url"`
	TournamentName string `json:"tournament_name"`
	PlayerDataJSON string `gorm:"column:player_data" json:"player_data_json"`
}

func main() {
	tournamentAlias := "qwewq_esad_1312"
	tournamentAliasSimple := ""
	index := strings.Index(tournamentAlias, "_")
	if index != -1 {
		//截取第一个 "_" 之前的所有字符
		tournamentAliasSimple = tournamentAlias[:index]
	} else {
		tournamentAliasSimple = tournamentAlias
	}
	fmt.Println(tournamentAliasSimple)
}

func ToFloat32(data interface{}) float32 {
	switch value := data.(type) {
	case int:
		return float32(value)
	case int64:
		return float32(value)
	case float64:
		return float32(value)
	case string:
		parsedValue, err := strconv.ParseFloat(value, 32)
		if err != nil {
			return 0
		}
		return float32(parsedValue)
	default:
		return 0
	}
}
func IsEmpty(data interface{}) bool {
	if data == nil {
		return true
	}

	val := reflect.Indirect(reflect.ValueOf(data))

	if val.Kind() != reflect.Struct {
		return false
	}

	return isStructEmpty(val)
}

func isStructEmpty(val reflect.Value) bool {
	for i := 0; i < val.NumField(); i++ {
		field := val.Field(i)

		switch field.Kind() {
		case reflect.Ptr, reflect.Interface:
			if !field.IsNil() {
				return false
			}
		case reflect.Struct:
			if !isStructEmpty(field) {
				return false
			}
		default:
			zero := reflect.Zero(field.Type())
			if !reflect.DeepEqual(field.Interface(), zero.Interface()) {
				return false
			}
		}
	}

	return true
}

type SortIntValueTypeInterface interface { //和平精英int类型排序泛型
	Test
}

type SortIntValueType[T SortIntValueTypeInterface] struct {
	Data []T
}

func (receiver *SortIntValueType[T]) SortIntValueType(sortArr []map[string]string) {
	data := receiver.Data
	if len(data) == 0 || len(sortArr) == 0 {
		return
	}
	//对结构体数据进行排序
	sort.Slice(data, func(i, j int) bool {
		for k := 0; k < len(sortArr); k++ {
			sType := reflect.TypeOf(data[i]) //获取单条的结构体数据
			var field string                 //结构体中定义的字段名
			for key, value := range sortArr[k] {
				//使用反射获取tag为json的标签值
				for x := 0; x < sType.NumField(); x++ {
					fieldType := sType.Field(x)
					if key == fieldType.Tag.Get("json") {
						field = fieldType.Name
						break
					}
				}
				//通过反射获取对应字段的value值进行排序
				switch reflect.ValueOf(data[i]).FieldByName(field).Kind() {
				case reflect.Int:
					if value == "desc" { //从大到小
						if reflect.ValueOf(data[i]).FieldByName(field).Int() > reflect.ValueOf(data[j]).FieldByName(field).Int() {
							return true
						} else if reflect.ValueOf(data[i]).FieldByName(field).Int() < reflect.ValueOf(data[j]).FieldByName(field).Int() {
							return false
						}
					} else if value == "asc" { //从小到大
						if reflect.ValueOf(data[i]).FieldByName(field).Int() > reflect.ValueOf(data[j]).FieldByName(field).Int() {
							return false
						} else if reflect.ValueOf(data[i]).FieldByName(field).Int() < reflect.ValueOf(data[j]).FieldByName(field).Int() {
							return true
						}
					}
				case reflect.String:
					if value == "desc" { //从大到小
						if reflect.ValueOf(data[i]).FieldByName(field).String() > reflect.ValueOf(data[j]).FieldByName(field).String() {
							return true
						} else if reflect.ValueOf(data[i]).FieldByName(field).String() < reflect.ValueOf(data[j]).FieldByName(field).String() {
							return false
						}
					} else if value == "asc" { //从小到大
						if reflect.ValueOf(data[i]).FieldByName(field).String() > reflect.ValueOf(data[j]).FieldByName(field).String() {
							return false
						} else if reflect.ValueOf(data[i]).FieldByName(field).String() < reflect.ValueOf(data[j]).FieldByName(field).String() {
							return true
						}
					}
				}
			}
		}
		return true
	})
}
